/*
 * Copyright 2014 Graham Smith
 */
package uk.co.wobblycogs.vegas;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Set;
import java.util.TreeSet;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.co.wobblycogs.vegas.scan.ScanResults;

/**
 *
 * @author Graham Smith
 */
public class HTMLReportGenerator {

	private static final Logger logger = LoggerFactory.getLogger(HTMLReportGenerator.class);

	public HTMLReportGenerator() {
	}

	public void generate(ScanResults results, Path reportPath) throws IOException {
		try {
			try (OutputStream destination = new FileOutputStream(reportPath.toFile())) {
				XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
				XMLStreamWriter xml = outputFactory.createXMLStreamWriter(destination);

				xml.writeStartDocument();
				xml.writeStartElement("html");
				xml.writeDefaultNamespace("http://www.w3.org/1999/xhtml");

				xml.writeStartElement("head");
				writeCSS(xml);
				xml.writeStartElement("title");
				xml.writeCharacters("Vegas Tools Report");
				xml.writeEndElement(); //title
				xml.writeEndElement(); //head

				writeUnusedMedia(results, xml);
				writeMediaProject(results, xml);
				writeProjectMedia(results, xml);
				writeDuration(results, xml);

				xml.writeEndElement(); //html
				xml.writeEndDocument();

				xml.close();
			}
		} catch (XMLStreamException xmle) {
			throw new RuntimeException("Failed to generate the report.", xmle);
		}
	}

	private void writeCSS(XMLStreamWriter xml) throws XMLStreamException {
		xml.writeStartElement("style");
		xml.writeAttribute("type", "text/css");
		String primary0 = "#656C99";
		String primary1 = "#7179AF";
		String primary2 = "#727AA9";
		String primary3 = "#59608C";
		String primary4 = "#515881";
		String secondaryA0 = "#786198";
		String secondaryA1 = "#876DAD";
		String secondaryA2 = "#866FA8";
		String secondaryA3 = "#6C568A";
		String secondaryA4 = "#624E7F";
		String secondaryB0 = "#55818A";
		String secondaryB1 = "#5E939D";
		String secondaryB2 = "#618F98";
		String secondaryB3 = "#4B757D";
		String secondaryB4 = "#436C73";
		String complement0 = "#E0C788";
		String complement1 = "#FFE197";
		String complement2 = "#F7DD9B";
		String complement3 = "#CCB477";
		String complement4 = "#BCA56C";

		xml.writeCharacters("div.header-1 {background-color: " + primary0 + "}\n"
				+ "div.header-2 {background-color: " + secondaryB0 + "}\n"
				+ "span.missing {color: red}\n"
		);
		xml.writeEndElement();
	}

	private void writeUnusedMedia(ScanResults results, XMLStreamWriter xml) throws XMLStreamException {
		writeHeader("Unused Media", 1, xml);

		xml.writeStartElement("ul");
//		for (Path p : results.getUnusedMedia()) {
//			xml.writeStartElement("li");
//			xml.writeCharacters(p.toString());
//			xml.writeEndElement();
//		}
		xml.writeEndElement();
	}

	private void writeMediaProject(ScanResults results, XMLStreamWriter xml) throws XMLStreamException {
		writeHeader("Project by Media", 1, xml);

		Set<Path> keys = new TreeSet<>(results.getMediaProjectResults().keySet());
		for (Path p : keys) {
			writeHeader(p.getFileName().toString(), 2, xml);

			xml.writeStartElement("p");
			xml.writeCharacters(p.toString());
			if (!Files.exists(p)) {
				xml.writeStartElement("span");
				xml.writeAttribute("class", "missing");
				xml.writeCharacters(" (missing)");
				xml.writeEndElement();
			}
			xml.writeEndElement();

			Set<Path> project = new TreeSet<>(results.getMediaProjectResults().get(p));
			xml.writeStartElement("ul");
			for (Path m : project) {
				xml.writeStartElement("li");
				xml.writeCharacters(m.toString());
				xml.writeEndElement();
			}
			xml.writeEndElement();
		}
	}

	private void writeProjectMedia(ScanResults results, XMLStreamWriter xml) throws XMLStreamException {
		writeHeader("Media by Project", 1, xml);

		Set<Path> keys = new TreeSet<>(results.getProjectMediaResults().keySet());
		for (Path p : keys) {
			writeHeader(FilenameUtils.getBaseName(p.getFileName().toString()), 2, xml);

			xml.writeStartElement("p");
			xml.writeCharacters(p.toString());
			xml.writeEndElement();

			Set<Path> media = new TreeSet<>(results.getProjectMediaResults().get(p));
			xml.writeStartElement("ul");
			for (Path m : media) {
				xml.writeStartElement("li");
				xml.writeCharacters(m.toString());
				if (!Files.exists(m)) {
					xml.writeStartElement("span");
					xml.writeAttribute("class", "missing");
					xml.writeCharacters(" (missing)");
					xml.writeEndElement();
				}
				xml.writeEndElement();
			}
			xml.writeEndElement();
		}
	}

	private void writeDuration(ScanResults results, XMLStreamWriter xml) throws XMLStreamException {
		xml.writeStartElement("p");
		xml.writeCharacters(VegasUtilities.formatDuration(results.getDuration()));
		xml.writeEndElement();
	}

	private void writeHeader(String header, int level, XMLStreamWriter xml) throws XMLStreamException {
		xml.writeStartElement("div");
		xml.writeAttribute("class", "header-" + level);
		xml.writeStartElement("h" + level);
		xml.writeCharacters(header);
		xml.writeEndElement();
		xml.writeEndElement();
	}

}
